package io.bd;

import io.Archivo;
import io.Carpeta;
import io.Cliente;
import io.ListaSincronizada;
import java.util.ArrayList;

/**
 *
 * @author Mariano Zapata
 */
public class Control {
    
    private ListaSincronizada<Cliente> clientesAbiertos;
    private ListaSincronizada<Archivo> archivosAbiertos;
    private ListaSincronizada<Carpeta> expedientesAbiertos;
    
    public Control()
    {
        clientesAbiertos= new ListaSincronizada<Cliente>();
        archivosAbiertos= new ListaSincronizada<Archivo>();
        expedientesAbiertos= new ListaSincronizada<Carpeta>();
    }
    
    public void abrirCliente(Cliente c) throws InterruptedException
    {
        clientesAbiertos.adquirir();
        for (Cliente l : clientesAbiertos)
        {
            if (l.equals(c))
            {
                clientesAbiertos.liberar();
                return;
            }
        }
        clientesAbiertos.add(c);
        clientesAbiertos.liberar();
    }

    public void abrirExpediente(Carpeta e) throws InterruptedException
    {
        expedientesAbiertos.adquirir();
        for (Carpeta x : expedientesAbiertos)
        {
            if (x.equals(e))
            {
                expedientesAbiertos.liberar();
                return;
            }
        }
        expedientesAbiertos.add(e);
        expedientesAbiertos.liberar();
    }
    
    public void abrirArchivo(Archivo a) throws InterruptedException
    {
        archivosAbiertos.adquirir();
        for (Archivo h : archivosAbiertos)
        {
            if (h.equals(a))
            {
                archivosAbiertos.liberar();
                return;
            }
        }
        archivosAbiertos.add(a);
        archivosAbiertos.liberar();
    }
    
    public void cerrarCliente(Cliente c) throws InterruptedException
    {
        clientesAbiertos.adquirir();
        clientesAbiertos.remove(c);
        clientesAbiertos.liberar();
    }

    public void cerrarExpediente(Carpeta e) throws InterruptedException
    {
        expedientesAbiertos.adquirir();
        expedientesAbiertos.remove(e);
        expedientesAbiertos.liberar();
    }
    
    public void cerrarArchivo(Archivo a) throws InterruptedException
    {
        archivosAbiertos.adquirir();
        archivosAbiertos.remove(a);
        archivosAbiertos.liberar();
    }
    
    public void cerrarTodos(int duenio) throws InterruptedException
    {
        ArrayList<Cliente> clientesAuxiliar= new ArrayList<Cliente>();
        ArrayList<Archivo> archivosAuxiliar= new ArrayList<Archivo>();
        ArrayList<Carpeta> expedientesAuxiliar= new ArrayList<Carpeta>();
        clientesAbiertos.adquirir();
        for (Cliente c : clientesAbiertos)
        {
            if (c.getDuenio() == duenio)
                clientesAuxiliar.add(c);
        }
        clientesAbiertos.removeAll(clientesAuxiliar);
        clientesAbiertos.liberar();
        expedientesAbiertos.adquirir();
        for (Carpeta e : expedientesAbiertos)
        {
            if (e.getDuenio() == duenio)
                expedientesAuxiliar.add(e);
        }
        expedientesAbiertos.removeAll(expedientesAuxiliar);
        expedientesAbiertos.liberar();
        archivosAbiertos.adquirir();
        for (Archivo h : archivosAbiertos)
        {
            if (h.getDuenio() == duenio)
                archivosAuxiliar.add(h);
        }
        archivosAbiertos.removeAll(archivosAuxiliar);
        archivosAbiertos.liberar();
    }
    
    public boolean estaAbiertoPorOtro(Cliente c) throws InterruptedException
    {
        clientesAbiertos.adquirir();
        for (Cliente l : clientesAbiertos)
        {
            if (l.equals(c))
            {
                if (l.getDuenio() != c.getDuenio())
                {
                    clientesAbiertos.liberar();
                    return true;
                }
                else
                {
                    clientesAbiertos.liberar();
                    return false;
                }
            }
        }
        clientesAbiertos.liberar();
        return false;
    }

    public boolean estaAbiertoPorOtro(Carpeta expediente) throws InterruptedException
    {
        expedientesAbiertos.adquirir();
        for (Carpeta x : expedientesAbiertos)
        {
            if (x.equals(expediente))
            {
                if (x.getDuenio() != expediente.getDuenio())
                {
                    expedientesAbiertos.liberar();
                    return true;
                }
                else
                {
                    expedientesAbiertos.liberar();
                    return false;
                }
            }
        }
        expedientesAbiertos.liberar();
        return false;
    }

    public boolean estaAbiertoPorOtro(Archivo a) throws InterruptedException
    {
        archivosAbiertos.adquirir();
        for (Archivo h : archivosAbiertos)
        {
            if (h.equals(a))
            {
                if (h.getDuenio() != a.getDuenio())
                {
                    archivosAbiertos.liberar();
                    return true;
                }
                else
                {
                    archivosAbiertos.liberar();
                    return false;
                }
            }
        }
        archivosAbiertos.liberar();
        return false;
    }
    
    public boolean estaAbierto(Cliente c) throws InterruptedException
    {
        clientesAbiertos.adquirir();
        for (Cliente l : clientesAbiertos)
        {
            if (l.equals(c))
            {
                clientesAbiertos.liberar();
                return true;
            }
        }
        clientesAbiertos.liberar();
        return false;
    }

    public boolean estaAbierto(Carpeta expediente) throws InterruptedException
    {
        expedientesAbiertos.adquirir();
        for (Carpeta x : expedientesAbiertos)
        {
            if (x.equals(expediente))
            {
                expedientesAbiertos.liberar();
                return true;
            }
        }
        expedientesAbiertos.liberar();
        return false;
    }
    
    public boolean estaAbierto(Archivo a) throws InterruptedException
    {
        archivosAbiertos.adquirir();
        for (Archivo h : archivosAbiertos)
        {
            if (h.equals(a))
            {
                archivosAbiertos.liberar();
                return true;
            }
        }
        archivosAbiertos.liberar();
        return false;
    }
    
    public boolean esEliminable(Carpeta c, int quienElimina) throws InterruptedException
    {
        clientesAbiertos.adquirir();
        for (Cliente l : clientesAbiertos)
        {
            if (l.estaEnRuta(c.obtenerId()) && l.getDuenio() != quienElimina)
            {
                clientesAbiertos.liberar();
                return false;
            }
        }
        clientesAbiertos.liberar();
        expedientesAbiertos.adquirir();
        for (Carpeta e : expedientesAbiertos)
        {
            if (e.estaEnRuta(c.obtenerId()) && e.getDuenio() != quienElimina)
            {
                expedientesAbiertos.liberar();
                return false;
            }
        }
        expedientesAbiertos.liberar();
        archivosAbiertos.adquirir();
        for (Archivo h : archivosAbiertos)
        {
            if (h.estaEnRuta(c.obtenerId()))
            {
                archivosAbiertos.liberar();
                return false;
            }
        }
        archivosAbiertos.liberar();
        return true;
    }
}
